using Autofac;
using Autofac.Extensions.DependencyInjection;
using Api.Config;
using Api.Filters;
using Serilog;
using SqlSugar;

namespace Api;

/// <summary>
/// 程序入口类
/// </summary>
/// <remarks>
/// 配置Web应用程序的服务、中间件和路由
/// </remarks>
public class Program
{
    /// <summary>
    /// 应用程序主入口点
    /// </summary>
    /// <param name="args">命令行参数</param>
    public static void Main(string[] args)
    {
        // 使用独立配置类初始化Serilog日志
        Log.Logger = LoggerConfig.CreateLogger();

        try
        {
            var builder = WebApplication.CreateBuilder(args);
            
            // 使用Serilog替换默认日志
            builder.Host.UseSerilog();

        // 替换内置IOC
        builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
        
        builder.Host.ConfigureContainer<ContainerBuilder>(container =>
        {
            #region 通过模块化方法注册接口层和实现层
            container.RegisterModule(new AutofacRegister());
            #endregion

            container.Register<ISqlSugarClient>(context =>
            {
                SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
                {
                    DbType = DbType.SqlServer,
                    IsAutoCloseConnection = true,
                    ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"),
                });
                
                // 配置SQL执行前事件：记录SQL日志
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    // 记录SQL执行日志
                    Log.Debug("执行SQL: {Sql}", sql);
                    if (pars != null && pars.Length > 0)
                    {
                        Log.Debug("参数: {Parameters}", string.Join(", ", pars.Select(p => $"{p.ParameterName}={p.Value}")));
                    }
                };
                
                db.Aop.DataExecuting = (oldValue, entityInfo) =>
                {
                    // 插入操作：自动设置CreateTime和UpdateTime
                    if (entityInfo.OperationType == DataFilterType.InsertByObject)
                    {
                        if (entityInfo.PropertyName == "CreateTime")
                        {
                            entityInfo.SetValue(DateTime.Now);
                        }
                        if (entityInfo.PropertyName == "UpdateTime")
                        {
                            entityInfo.SetValue(DateTime.Now);
                        }
                    }
                    
                    // 更新操作：自动设置UpdateTime
                    if (entityInfo.OperationType == DataFilterType.UpdateByObject)
                    {
                        if (entityInfo.PropertyName == "UpdateTime")
                        {
                            entityInfo.SetValue(DateTime.Now);
                        }
                    }
                };
                
                return db;
            });
        });

        // AutoMapper映射
        builder.Services.AddAutoMapper(typeof(AutoMapperConfigs));
         
        // 注册全局异常过滤器
        builder.Services.AddControllers(options =>
        {
            options.Filters.Add<GlobalExceptionFilter>();
        });

        // 配置Swagger/OpenAPI
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
            {
                Title = "学生管理系统 API",
                Version = "v1",
                Description = "学生管理系统的RESTful API接口文档",
            });

            // 启用XML注释
            var xmlFile = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            if (File.Exists(xmlPath))
            {
                options.IncludeXmlComments(xmlPath, includeControllerXmlComments: true);
            }
        });

        var app = builder.Build();

        // Configure the HTTP request pipeline.
        
        // 启用Swagger中间件
        app.UseSwagger();
        app.UseSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "学生管理系统 API v1");
            options.RoutePrefix = string.Empty; // 设置Swagger UI为默认启动页面（根路径）
            options.DocumentTitle = "学生管理系统 API 文档";
        });

        app.UseAuthorization();

        app.MapControllers();

        Log.Information("应用程序启动成功");
        app.Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "应用程序启动失败");
            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}